/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.chronicles.tapestry.base;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Response;
import org.libermundi.theorcs.chronicles.dto.ChronicleSettings;
import org.libermundi.theorcs.chronicles.model.Chronicle;
import org.libermundi.theorcs.chronicles.model.Persona;
import org.libermundi.theorcs.chronicles.model.SavedInformations;
import org.libermundi.theorcs.chronicles.services.SavedInformationsManager;
import org.libermundi.theorcs.chronicles.tapestry.pages.Index;
import org.libermundi.theorcs.core.exceptions.RedirectException;
import org.libermundi.theorcs.core.tapestry.services.AppHelper;
import org.libermundi.theorcs.core.tapestry.services.PageRenderSupport;
import org.libermundi.theorcs.layout.LayoutConstants;
import org.libermundi.theorcs.layout.dto.TemplateSettings;
import org.libermundi.theorcs.layout.model.TemplateType;
import org.libermundi.theorcs.security.model.User;
import org.libermundi.theorcs.security.services.SecurityManager;
import org.libermundi.theorcs.security.tapestry.base.PrivatePage;
import org.slf4j.Logger;
import org.springframework.security.acls.AclPermissionEvaluator;
import org.springframework.security.acls.domain.BasePermission;

import com.google.common.base.Strings;


/**
 * Internal Page with all the Session objects
 *
 */
@Import(stylesheet="${layout.styles}/smoothness.css")
public abstract class ChroniclePage extends PrivatePage {
	@Inject
	private SecurityManager _securityManager;
	
	@Inject
	private AclPermissionEvaluator _aclPermissionEvaluator;
	
	@SessionState
	private ChronicleSettings _chronicleSettings;
	
	@SessionState
	private TemplateSettings _templateSettings;
	
	@Environmental
	private PageRenderSupport _pageRenderSupport;
	
	@Inject
	private SavedInformationsManager _savedInfosManager;	

	@Inject
	private AppHelper _appHelper;
	
	@Inject
	private Response _response;
	
	@Inject
	private Messages _messages;
	
	@Inject
	private Logger _logger;
	
	@Parameter(defaultPrefix = BindingConstants.LITERAL)
	private Block _sideBar;
	
	@SetupRender
	public void checkReadSecurity() {
		// Setup the NavBar rendering
		Chronicle chronicle = _chronicleSettings.getChronicle();
		
		if( chronicle == null || !_securityManager.hasPermission(chronicle, BasePermission.READ)) {
			if(chronicle== null) {
				_logger.error("No Chronicle available from Context");
			} else {
				_logger.error("Acces to Chronicle {} forbiden for current user {}",_chronicleSettings.getChronicle().getTitle(), _securityManager.getCurrentUsername());
			}
			sendRedirect();
			return;
		}
		
		_pageRenderSupport.setProperty(LayoutConstants.INDEX_PAGELABEL, chronicle.getTitle());
		_pageRenderSupport.setProperty(LayoutConstants.INDEX_PAGETITLE, chronicle.getTitle() + ((!Strings.isNullOrEmpty(chronicle.getSubTitle())) ? " - " + chronicle.getSubTitle() : ""));
		_pageRenderSupport.setProperty(LayoutConstants.INDEX_PAGENAME, _appHelper.getPageNameFromClass(Index.class));
		
		//TODO: Improve later. Depends if the users have the possibility to change Template or not in future.
		_templateSettings.setTemplateType(TemplateType.STATIC);
		_templateSettings.setCurrentTemplate(LayoutConstants.DEFAULT_CHRONICLE_TEMPLATE_CODE);
		
		if(_logger.isDebugEnabled()){
			_logger.debug("Access has been granted to Chronicle : '{}' and to Persona : '{}'",_chronicleSettings.getChronicle().getTitle(),_chronicleSettings.getPersona().getName());
		}
	}

	protected void sendRedirect(){
		Link redirectTo = _appHelper.getPageLink("Index");
		User user = _securityManager.getCurrentUser();
		if(user != null) {
			_logger.info("Reloading Last Saved Information (if any)");
			SavedInformations infos = _savedInfosManager.getByUser(user);
			if(infos != null) {
				long chronicleId = Long.valueOf(infos.readInformation("chronicleId"));
				if(chronicleId > 0L) {
					redirectTo = _appHelper.getPageLink(Index.class, chronicleId);
				}
			} else {
				_logger.error("No Saved Informations for User : " + user.getUsername());
				redirectTo = _appHelper.getPageLink("Index");
			}
		}
		throw new RedirectException(redirectTo);
	}

	public String getChronicleName(){
		return _chronicleSettings.getChronicle().getTitle();
	}
	
	public ChronicleSettings getChronicleSettings(){
		return _chronicleSettings;
	}
	
	public Messages getMessages(){
		return _messages;
	}
	
	public Persona getCurrentPerso(){
		return getChronicleSettings().getPersona();
	}
	
}
